home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / Apps / Astro / ephem / Source / formats.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-12  |  7.3 KB  |  388 lines

  1. /* basic formating routines.
  2.  * all the screen oriented printing should go through here.
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <math.h>
  7. #include <ctype.h>
  8. #ifdef VMS
  9. #include <stdlib.h>
  10. #endif
  11. #ifdef NeXT
  12. # include <stdlib.h>
  13. #endif
  14. #include "astro.h"
  15. #include "screen.h"
  16.  
  17. extern char *strcpy();
  18.  
  19. /* suppress screen io if this is true, but always flog stuff.
  20.  */
  21. static int f_scrnoff;
  22. f_on ()
  23. {
  24.     f_scrnoff = 0;
  25. }
  26. f_off ()
  27. {
  28.     f_scrnoff = 1;
  29. }
  30.  
  31. /* draw n blanks at the given cursor position.  */
  32. f_blanks (r, c, n)
  33. int r, c, n;
  34. {
  35.     if (f_scrnoff)
  36.         return;
  37.     c_pos (r, c);
  38.     while (--n >= 0)
  39.         putchar (' ');
  40. }
  41.  
  42. /* print the given value, v, in "sexadecimal" format at [r,c]
  43.  * ie, in the form A:m.P, where A is a digits wide, P is p digits.
  44.  * if p == 0, then no decimal point either.
  45.  */
  46. f_sexad (r, c, a, p, mod, v)
  47. int r, c;
  48. int a, p;    /* left space, min precision */
  49. int mod;    /* don't let whole portion get this big */
  50. double v;
  51. {
  52.     char astr[32], str[32];
  53.     long dec;
  54.     double frac;
  55.     int visneg;
  56.     double vsav = v;
  57.  
  58.     if (v >= 0.0)
  59.         visneg = 0;
  60.     else {
  61.         if (v <= -0.5/60.0*pow(10.0,-1.0*p)) {
  62.         v = -v;
  63.         visneg = 1;
  64.         } else {
  65.         /* don't show as negative if less than the precision showing */
  66.         v = 0.0;
  67.         visneg = 0;
  68.         }
  69.     }
  70.  
  71.     dec = v;
  72.     frac = (v - dec)*60.0;
  73.     (void) sprintf (str, "59.%.*s5", p, "999999999");
  74.     if (frac >= atof (str)) {
  75.         dec += 1;
  76.         frac = 0.0;
  77.     }
  78.     dec %= mod;
  79.     if (dec == 0 && visneg)
  80.         (void) strcpy (str, "-0");
  81.     else
  82.         (void) sprintf (str, "%ld", visneg ? -dec : dec);
  83.  
  84.     /* would just do this if Turbo-C 2.0 %?.0f" worked:
  85.      * sprintf (astr, "%*s:%0*.*f", a, str, p == 0 ? 2 : p+3, p, frac);
  86.      */
  87.     if (p == 0)
  88.         (void) sprintf (astr, "%*s:%02d", a, str, (int)(frac+0.5));
  89.     else
  90.         (void) sprintf (astr, "%*s:%0*.*f", a, str, p+3, p, frac);
  91.  
  92.     (void) flog_log (r, c, vsav, astr);
  93.  
  94.     f_string (r, c, astr);
  95. }
  96.  
  97. /* print the given value, t, in sexagesimal format at [r,c]
  98.  * ie, in the form T:mm:ss, where T is nd digits wide.
  99.  * N.B. we assume nd >= 2.
  100.  */
  101. f_sexag (r, c, nd, t)
  102. int r, c, nd;
  103. double t;
  104. {
  105.     char tstr[32];
  106.     int h, m, s;
  107.     int tisneg;
  108.     
  109.     dec_sex (t, &h, &m, &s, &tisneg);
  110.     if (h == 0 && tisneg)
  111.         (void) sprintf (tstr, "%*s-0:%02d:%02d", nd-2, "", m, s);
  112.     else
  113.         (void) sprintf (tstr, "%*d:%02d:%02d", nd, tisneg ? -h : h, m, s);
  114.  
  115.     (void) flog_log (r, c, t, tstr);
  116.     f_string (r, c, tstr);
  117. }
  118.  
  119. /* print angle ra, in radians, in ra hours as hh:mm.m at [r,c]
  120.  * N.B. we assume ra is >= 0.
  121.  */
  122. f_ra (r, c, ra)
  123. int r, c;
  124. double ra;
  125. {
  126.     f_sexad (r, c, 2, 1, 24, radhr(ra));
  127. }
  128.  
  129. /* print time, t, as hh:mm:ss */
  130. f_time (r, c, t)
  131. int r, c;
  132. double t;
  133. {
  134.     f_sexag (r, c, 2, t);
  135. }
  136.  
  137. /* print time, t, as +/-hh:mm:ss (don't show leading +) */
  138. f_signtime (r, c, t)
  139. int r, c;
  140. double t;
  141. {
  142.     f_sexag (r, c, 3, t);
  143. }
  144.  
  145. /* print time, t, as hh:mm */
  146. f_mtime (r, c, t)
  147. int r, c;
  148. double t;
  149. {
  150.     f_sexad (r, c, 2, 0, 24, t);
  151. }
  152.  
  153. /* print angle, a, in rads, as degress at [r,c] in form ddd:mm */
  154. f_angle(r, c, a)
  155. int r, c;
  156. double a;
  157. {
  158.     f_sexad (r, c, 3, 0, 360, raddeg(a));
  159. }
  160.  
  161. /* print angle, a, in rads, as degress at [r,c] in form dddd:mm:ss */
  162. f_gangle(r, c, a)
  163. int r, c;
  164. double a;
  165. {
  166.     f_sexag (r, c, 4, raddeg(a));
  167. }
  168.  
  169. /* print the given modified Julian date, jd, as the starting date at [r,c]
  170.  * in the form mm/dd/yyyy.
  171.  */
  172. f_date (r, c, jd)
  173. int r, c;
  174. double jd;
  175. {
  176.     char dstr[32];
  177.     int m, y;
  178.     double d, tmp;
  179.  
  180.     mjd_cal (jd, &m, &d, &y);
  181.     (void) sprintf (dstr, "%2d/%02d/%-4d", m, (int)(d), y);
  182.  
  183.     /* shadow to the plot subsystem as years. */
  184.     mjd_year (jd, &tmp);
  185.     (void) flog_log (r, c, tmp, dstr);
  186.     f_string (r, c, dstr);
  187. }
  188.  
  189. /* print the given double as a rounded int, with the given format.
  190.  * this is used to plot full precision, but display far less.
  191.  * N.B. caller beware that we really do expect fmt to refer to an int, not
  192.  *   a long for example. also beware of range that implies.
  193.  */
  194. f_int (row, col, fmt, f)
  195. int row, col;
  196. char fmt[];
  197. double f;
  198. {
  199.     char str[80];
  200.     int i;
  201.  
  202.     i = (f < 0) ? (int)(f-0.5) : (int)(f+0.5);
  203.     (void) sprintf (str, fmt, i);
  204.  
  205.     (void) flog_log (row, col, f, str);
  206.     f_string (row, col, str);
  207. }
  208.  
  209. f_char (row, col, c)
  210. int row, col;
  211. char c;
  212. {
  213.     if (f_scrnoff)
  214.         return;
  215.     c_pos (row, col);
  216.     putchar (c);
  217. }
  218.  
  219. f_string (r, c, s)
  220. int r, c;
  221. char *s;
  222. {
  223.     if (f_scrnoff)
  224.         return;
  225.     c_pos (r, c);
  226.     (void) fputs (s, stdout);
  227. }
  228.  
  229. f_double (r, c, fmt, f)
  230. int r, c;
  231. char *fmt;
  232. double f;
  233. {
  234.     char str[80];
  235.     (void) sprintf (str, fmt, f);
  236.     (void) flog_log (r, c, f, str);
  237.     f_string (r, c, str);
  238. }
  239.  
  240. /* print prompt line */
  241. f_prompt (p)
  242. char *p;
  243. {
  244.     c_pos (R_PROMPT, C_PROMPT);
  245.     c_eol ();
  246.     c_pos (R_PROMPT, C_PROMPT);
  247.     (void) fputs (p, stdout);
  248. }
  249.  
  250. /* clear from [r,c] to end of line, if we are drawing now. */
  251. f_eol (r, c)
  252. int r, c;
  253. {
  254.     if (!f_scrnoff) {
  255.         c_pos (r, c);
  256.         c_eol();
  257.     }
  258. }
  259.  
  260. /* print a message and wait for op to hit any key */
  261. f_msg (m)
  262. char *m;
  263. {
  264.     f_prompt (m);
  265.     (void) read_char();
  266. }
  267.  
  268. /* crack a line of the form X?X?X into its components,
  269.  *   where X is an integer and ? can be any character except '0-9' or '-',
  270.  *   such as ':' or '/'.
  271.  * only change those fields that are specified:
  272.  *   eg:  ::10    only changes *s
  273.  *        10    only changes *d
  274.  *        10:0  changes *d and *m
  275.  * if see '-' anywhere, first non-zero component will be made negative.
  276.  */
  277. f_sscansex (bp, d, m, s)
  278. char *bp;
  279. int *d, *m, *s;
  280. {
  281.     char c;
  282.     int *p = d;
  283.     int *nonzp = 0;
  284.     int sawneg = 0;
  285.     int innum = 0;
  286.  
  287.     while (c = *bp++)
  288.         if (isdigit(c)) {
  289.         if (!innum) {
  290.             *p = 0;
  291.             innum = 1;
  292.         }
  293.         *p = *p*10 + (c - '0');
  294.         if (*p && !nonzp)
  295.             nonzp = p;
  296.         } else if (c == '-') {
  297.         sawneg = 1;
  298.         } else if (c != ' ') {
  299.         /* advance to next component */
  300.         p = (p == d) ? m : s;
  301.         innum = 0;
  302.         }
  303.  
  304.     if (sawneg && nonzp)
  305.         *nonzp = -*nonzp;
  306. }
  307.  
  308. /* crack a floating date string, bp, of the form m/d/y, where d may be a
  309.  *   floating point number, into its components.
  310.  * leave any component unspecified unchanged.
  311.  * actually, the slashes may be anything but digits or a decimal point.
  312.  * this is functionally the same as f_sscansex() exept we allow for
  313.  *   the day portion to be real, and we don't handle negative numbers.
  314.  *   maybe someday we could make a combined one and use it everywhere.
  315.  */
  316. f_sscandate (bp, m, d, y)
  317. char *bp;
  318. int *m, *y;
  319. double *d;
  320. {
  321.     char *bp0, c;
  322.  
  323.     bp0 = bp;
  324.     while ((c = *bp++) && isdigit(c))
  325.         continue;
  326.     if (bp > bp0+1)
  327.         *m = atoi (bp0);
  328.     if (c == '\0')
  329.         return;
  330.     bp0 = bp;
  331.     while ((c = *bp++) && (isdigit(c) || c == '.'))
  332.         continue;
  333.     if (bp > bp0+1)
  334.         *d = atof (bp0);
  335.     if (c == '\0')
  336.         return;
  337.     bp0 = bp;
  338.     while (c = *bp++)
  339.         continue;
  340.     if (bp > bp0+1)
  341.         *y = atoi (bp0);
  342. }
  343.  
  344. /* just like dec_sex() but makes the first non-zero element negative if
  345.  * x is negative (instead of returning a sign flag).
  346.  */
  347. f_dec_sexsign (x, h, m, s)
  348. double x;
  349. int *h, *m, *s;
  350. {
  351.     int n;
  352.     dec_sex (x, h, m, s, &n);
  353.     if (n) {
  354.         if (*h)
  355.         *h = -*h;
  356.         else if (*m)
  357.         *m = -*m;
  358.         else
  359.         *s = -*s;
  360.     }
  361. }
  362.  
  363. /* return 1 if bp looks like a decimal year; else 0.
  364.  * any number greater than 12 or less than 0 is assumed to be a year, or any
  365.  * string with exactly one decimal point, an optional minus sign, and nothing
  366.  * else but digits.
  367.  */
  368. decimal_year (bp)
  369. char *bp;
  370. {
  371.     char c;
  372.     int ndig = 0, ndp = 0, nneg = 0, nchar = 0;
  373.     double y = atof(bp);
  374.  
  375.     while (c = *bp++) {
  376.         nchar++;
  377.         if (isdigit(c))
  378.         ndig++;
  379.         else if (c == '.')
  380.         ndp++;
  381.         else if (c == '-')
  382.         nneg++;
  383.     }
  384.  
  385.     return (y > 12 || y < 0
  386.             || (ndp == 1 && nneg <= 1 && nchar == ndig+ndp+nneg));
  387. }
  388.